import asyncio
import json
import logging

from flask import request

from camera import camera_bp
from websocket.websocket_server import websocket_server
from .service import get_all_cameras, add_cameras, get_camera_by_id, update_camera, update_camera_path, \
    update_camera_ir, update_camera_gain, update_camera_mode, update_camera_color, update_camera_alarm, \
    update_camera_speed, get_camera_preset, get_camera_path_byid, add_camera_preset, add_camera_path, del_camera_preset, \
    upload_file, save_websocket_message, get_websocket_messages
from utils.tool import response

# 获取日志记录器
logger = logging.getLogger(__name__)


# 获取所有摄像头信息
@camera_bp.route('/list', methods=['GET'])
def cameras_info_list():
    try:
        cameras_list = get_all_cameras()
        logger.info('Cameras retrieved successfully')
        return response(200, data=cameras_list, msg='Cameras retrieved successfully')
    except Exception as e:
        logger.error(f'Error retrieving cameras: {e}')
        return response(500, msg=f'Error retrieving cameras: {e}')


@camera_bp.route('/info', methods=['GET'])
def camera_info():
    try:
        id = request.args.get('id', type=int)
        if id is None:
            return response(400, msg='Camera ID is required')
        camera = get_camera_by_id(id)
        if camera:
            logger.info(f'Camera {id} retrieved successfully')
            return response(200, data=camera, msg=f'Camera {id} retrieved successfully')
        else:
            return response(404, msg=f'Camera {id} not found')
    except Exception as e:
        logger.error(f'Error retrieving camera {id}: {e}')
        return response(500, msg=f'Error retrieving camera {id}: {e}')


# 新增摄像头
@camera_bp.route('/add', methods=['POST'])
def cameras_add():
    try:
        camera_list = request.json.get('cameras', [])
        if not camera_list or len(camera_list) > 6:
            return response(400, msg='Invalid camera list. Must contain 1 to 6 cameras.')

        if add_cameras(camera_list):
            logger.info('Cameras added successfully')
            return response(200, msg='Cameras added successfully')
        else:
            return response(500, msg='Failed to add cameras')
    except Exception as e:
        logger.error(f'Error adding cameras: {e}')
        return response(500, msg=f'Error adding cameras: {e}')


# 修改摄像头基础信息，包括id，名称，视频路径，排序
@camera_bp.route('/update-basic', methods=['POST'])
def camera_basic_update():
    try:
        id = request.json.get('id')
        camera_id = request.json.get('camera_id')
        name = request.json.get('name')
        video_url = request.json.get('video_url')
        sort = request.json.get('sort')
        if not id or not camera_id or not name or not video_url or (not sort and sort != 0):
            return response(400, msg='Invalid camera information')
        if update_camera(id, camera_id, name, video_url, sort):
            logger.info(f'Camera {id} updated successfully')
            return response(200, msg=f'Camera {id} updated successfully')
        else:
            return response(500, msg=f'Failed to update camera {id}')
    except Exception as e:
        logger.error(f'Error updating camera {id}: {e}')
        return response(500, msg=f'Error updating camera {id}: {e}')


# 修改摄像头路径配置信息，包括截图存储路径、录像存储路径、报警抓拍存储路径
@camera_bp.route('/update-path', methods=['POST'])
def camera_path_update():
    try:
        id = request.json.get('id')
        screenshot_url = request.json.get('screenshot_url')
        video_path = request.json.get('video_path')
        alarm_screenshot_url = request.json.get('alarm_screenshot_url')
        if not id or not screenshot_url or not video_path or not alarm_screenshot_url:
            return response(400, msg='Invalid camera path information')
        if update_camera_path(id, screenshot_url, video_path, alarm_screenshot_url):
            logger.info(f'Camera {id} path updated successfully')
            return response(200, msg=f'Camera {id} path updated successfully')
        else:
            return response(500, msg=f'Failed to update camera {id} path')
    except Exception as e:
        logger.error(f'Error updating camera {id} path: {e}')
        return response(500, msg=f'Error updating camera {id} path: {e}')


# 修改摄像头IR参数信息，包括发射率、反射温度、环境温度、相对湿度、测温距离
@camera_bp.route('/update-ir', methods=['POST'])
def camera_ir_update():
    try:
        id = request.json.get('id')
        reflection_rate = request.json.get('reflection_rate')
        reflection_temperature = request.json.get('reflection_temperature')
        environment_temperature = request.json.get('environment_temperature')
        relative_humidity = request.json.get('relative_humidity')
        temperature_distance = request.json.get('temperature_distance')
        if not id or not reflection_rate or not reflection_temperature or not environment_temperature or not relative_humidity or not temperature_distance:
            return response(400, msg='Invalid camera ir information')
        if update_camera_ir(id, reflection_rate, reflection_temperature, environment_temperature, relative_humidity,
                            temperature_distance):
            logger.info(f'Camera {id} ir updated successfully')
            return response(200, msg=f'Camera {id} ir updated successfully')
        else:
            return response(500, msg=f'Failed to update camera {id} ir')
    except Exception as e:
        logger.error(f'Error updating camera {id} ir: {e}')
        return response(500, msg=f'Error updating camera {id} ir: {e}')


# 修改摄像头增益信息
@camera_bp.route('/update-gain', methods=['POST'])
def camera_gain_update():
    try:
        id = request.json.get('id')
        gain = request.json.get('gain')
        if not id or (not gain and gain != 0):
            return response(400, msg='Invalid camera gain information')
        if update_camera_gain(id, gain):
            logger.info(f'Camera {id} gain updated successfully')
            return response(200, msg=f'Camera {id} gain updated successfully')
        else:
            return response(500, msg=f'Failed to update camera {id}gain')
    except Exception as e:
        logger.error(f'Error updating camera {id} gain: {e}')
        return response(500, msg=f'Error updating camera {id} gain: {e}')


# 修改摄像头模式信息
@camera_bp.route('/update-mode', methods=['POST'])
def camera_mode_update():
    try:
        id = request.json.get('id')
        mode = request.json.get('mode')
        if not id or not mode:
            return response(400, msg='Invalid camera mode information')
        if update_camera_mode(id, mode):
            logger.info(f'Camera {id} mode updated successfully')
            return response(200, msg=f'Camera {id} mode updated successfully')
        else:
            return response(500, msg=f'Failed to update camera {id}mode')
    except Exception as e:
        logger.error(f'Error updating camera {id} mode: {e}')
        return response(500, msg=f'Error updating camera {id} mode: {e}')


# 修改摄像头电晕颜色信息
@camera_bp.route('/update-color', methods=['POST'])
def camera_color_update():
    try:
        id = request.json.get('id')
        color = request.json.get('color')
        if not id or not color:
            return response(400, msg='Invalid camera color information')
        if update_camera_color(id, color):
            logger.info(f'Camera {id} color updated successfully')
            return response(200, msg=f'Camera {id} color updated successfully')
        else:
            return response(500, msg=f'Failedto update camera {id} color')
    except Exception as e:
        logger.error(f'Error updating camera {id} color: {e}')
        return response(500, msg=f'Error updating camera {id} color: {e}')


# 修改摄像头报警设置 包括紫外光子数、红外温度
@camera_bp.route('/update-alarm', methods=['POST'])
def camera_alarm_update():
    try:
        id = request.json.get('id')
        ir_photons = request.json.get('ir_photons')
        ir_temperature = request.json.get('ir_temperature')
        if not id or not ir_photons or not ir_temperature:
            return response(400, msg='Invalid camera alarm information')
        if update_camera_alarm(id, ir_photons, ir_temperature):
            logger.info(f'Camera {id} alarm updated successfully')
            return response(200, msg=f'Camera {id} alarm updated successfully')
        else:
            return response(500, msg=f'Failed to update camera {id} alarm')
    except Exception as e:
        logger.error(f'Error updating camera {id} alarm: {e}')
        return response(500, msg=f'Error updating camera {id} alarm: {e}')


# 修改摄像头转动速度
@camera_bp.route('/update-speed', methods=['POST'])
def camera_speed_update():
    try:
        id = request.json.get('id')
        speed = request.json.get('speed')
        if not id or not speed:
            return response(400, msg='Invalid camera speed information')
        if update_camera_speed(id, speed):
            logger.info(f'Camera {id} speed updated successfully')
            return response(200, msg=f'Camera {id} speed updated successfully')
        else:
            return response(500, msg=f'Failed to update camera {id} speed')
    except Exception as e:
        logger.error(f'Error updating camera {id} speed: {e}')
        return response(500, msg=f'Error updating camera {id} speed: {e}')


# 摄像头预制点名称查询
@camera_bp.route('/get-preset', methods=['POST'])
def camera_preset_get():
    try:
        camera_id = request.json.get('camera_id')
        if not camera_id:
            return response(400, msg='Invalid camera preset information')
        presets = get_camera_preset(camera_id)
        logger.info(f'Camera {camera_id} preset get successfully')
        return response(200, data=presets, msg=f'Camera {camera_id} preset get successfully')

    except Exception as e:
        logger.error(f'Error getting camera {camera_id} preset: {e}')
        return response(500, msg=f'Error getting camera {camera_id} preset: {e}')


# 添加摄像头预置点名称
@camera_bp.route('/add-preset', methods=['POST'])
def camera_preset_add():
    try:
        camera_id = request.json.get('camera_id')
        preset_name = request.json.get('preset_name')
        uid = request.json.get('uid')
        if not camera_id or not preset_name or not uid:
            return response(400, msg='Invalid camera preset information')
        if add_camera_preset(camera_id, preset_name, uid):
            logger.info(f'Camera {camera_id} preset added successfully')
            return response(200, msg=f'Camera {camera_id} presetadded successfully')
    except Exception as e:
        logger.error(f'Error adding camera {camera_id} preset: {e}')
        return response(500, msg=f'Error adding camera {camera_id} preset: {e}')

# 删除摄像头预置点名称
@camera_bp.route('/del-preset', methods=['POST'])
def camera_preset_del():
    try:
        id = request.json.get('id')
        if not id:
            return response(400, msg='Invalid camera preset information')
        if del_camera_preset(id):
            logger.info(f'Camera {id} preset deleted successfully')
            return response(200, msg=f'Camera {id} presetdeleted successfully')
        else:
            return response(500, msg=f'Failed to delete camera {id} preset')
    except Exception as e:
        logger.error(f'Error deleting camera {id} preset: {e}')
        return response(500, msg=f'Error deleting camera {id} preset: {e}')

# 摄像头路径巡航名称查询
@camera_bp.route('/get-path', methods=['POST'])
def camera_path_get():
    try:
        camera_id = request.json.get('camera_id')
        if not camera_id:
            return response(400, msg='Invalid camera path information')
        paths = get_camera_path_byid(camera_id)

        logger.info(f'Camera {camera_id} path get successfully')
        return response(200, data=paths, msg=f'Camera {camera_id} path get successfully')

    except Exception as e:
        logger.error(f'Error getting camera {camera_id} path: {e}')
        return response(500, msg=f'Error getting camera {camera_id} path: {e}')


# 添加摄像头路径巡航名称
@camera_bp.route('/add-path', methods=['POST'])
def camera_path_add():
    try:
        id = request.json.get('id')
        camera_id = request.json.get('camera_id')
        preset_ids = request.json.get('preset_ids')
        interval = request.json.get('interval')
        if not camera_id or not preset_ids or not interval:
            return response(400, msg='Invalid camera path information')
        if add_camera_path(id, camera_id, preset_ids, interval):
            logger.info(f'Camera {camera_id} path added successfully')
            return response(200, msg=f'Camera {camera_id} path added successfully')
        else:
            return response(500, msg=f'Failed to add camera {camera_id} path')
    except Exception as e:
        logger.error(f'Error adding camera {camera_id} path: {e}')
        return response(500, msg=f'Error adding camera {camera_id} path: {e}')


# 发送websocket消息
@camera_bp.route('/send-websocket', methods=['POST'])
def camera_send_websocket():
    try:
        message = request.json.get('message')
        if not message:
            return response(400, msg='Invalid camera websocket information')
        # message 为object处理成字符串
        if isinstance(message, dict):
            message = json.dumps(message)

        # 动态获取当前事件循环
        loop = websocket_server.loop
        if loop is None or not loop.is_running():
            return response(500, msg="Event loop is not running")
        logger.info(f'view全局事件循环 ID: {id(loop)}')
        logger.info(f'clients: {websocket_server.clients}')  # 添加日志记录当前客户端数量

        future = asyncio.run_coroutine_threadsafe(websocket_server.send_message(message), loop)
        try:
            future.result(timeout=5)  # 设置超时时间为5秒
        except TimeoutError:
            logger.error("Timeout sending camera websocket message")
            return response(500, msg="Timeout sending camera websocket message")
        # 发送消息
        if save_websocket_message(json.loads(message)):
            logger.info(f'Camera websocket message sent successfully')
            return response(200, msg=f'Camera websocket message sent successfully')
        else:
            return response(500, msg=f'Failed to send camera websocket message')
    except Exception as e:
        logger.error(f'Error sending camera websocket message: {e}')
        return response(500, msg=f'Error sending camera websocket message: {e}')

# 查询websocket消息
@camera_bp.route('/get-websocket-message', methods=['POST'])
def camera_get_websocket():
    try:
        camera_id = request.json.get('camera_id')
        date = request.json.get('date')
        if not camera_id:
            return response(400, msg='Invalid camera websocket message information')
        messages = get_websocket_messages(camera_id, date)
        if messages is None:
            return response(404, msg=f'Camera {camera_id} websocket message not found')
        else:
            logger.info(f'Camera {camera_id} websocket message get successfully')
            return response(200, data=messages, msg=f'Camera {camera_id} websocket message get successfully')
    except Exception as e:
        logger.error(f'Error getting camera {camera_id} websocket message: {e}')
        return response(500, msg=f'Error getting camera {camera_id} websocket message: {e}')

# 文件上传接口
@camera_bp.route('/upload', methods=['POST'])
def camera_upload():
    try:
        camera_id = request.form.get('camera_id')
        type = request.form.get('type')
        file = request.files.get('file')
        if not camera_id or not type or not file:
            return response(400, msg='Invalid camera file information')
        if upload_file(camera_id, type, file):
            return response(200, msg=f'Camera {camera_id} file uploaded successfully')
        else:
            return response(500, msg=f'Failed to upload camera {camera_id} file')
    except Exception as e:
        logger.error(f'Error uploading camera {camera_id} file: {e}')
        return response(500, msg=f'Error uploading camera {camera_id} file: {e}')

